package io.renren.common.weixin;


import io.renren.common.utils.HttpClient;
import net.sf.json.JSONObject;
import org.springframework.stereotype.Service;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by whc on 2017/5/6.
 */
@Service
public class WeiXinAccessTokenService {
    /**
     * 存放accessToken，key:appid+appSecret value:accessToken
     */
    private static Map<String, AccessToken> accessTokenMap = new HashMap<String, AccessToken>();
    /**
     *用于循环获取accesstoken记数用
     */
    private int number = 0;

    /**
     * 根据公众号的appid和appsecret获取accesstoken
     * 1、根据appid和appsecret在本地静态变量中查找accesstoken，
     * 如果有且在有效时间内（有效时间7200秒）则返回此accesstoken。
     * 2、如果没有则调用微信接口获取accsstoken，并保存到静态变量中，同时记录有效时间。
     * @param appId
     * @param appSecret
     * @return
     */
    public String getAccessToken(String appId, String appSecret) {
        String key = appId + appSecret;
        AccessToken accessToken = accessTokenMap.get(key);
        if (accessToken != null){
            //如果静态map中有存放accesstoken并且没有过期，则直接返回次token
            if (accessToken.getExpiresDate().after(new Date())){
                return accessToken.getAccessToken();
            }

        }
        try {
            AccessToken accessTokenFromWX = getAccessTokenFromWX(appId, appSecret);
            accessTokenMap.put(appId + appSecret, accessTokenFromWX);
            return accessTokenFromWX.getAccessToken();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }

    public AccessToken getAccessTokenFromWX(String appId, String appSecret) throws Exception{
        if (number > 3){
            throw new Exception("连续3次获取accesstoken失败，是稍候重试！");
        }
        String url = "https://api.weixin.qq.com/cgi-bin/token";
        String param = "grant_type=client_credential&appid="+appId+"&secret="+appSecret;
        HttpClient client = new HttpClient();
        String result = client.sendGet(url, param);
        JSONObject jsonData = JSONObject.fromObject(result);
        //如获取token失败，则重试3次后，3次后抛出异常
        if (jsonData.has("errcode")){
            number++;
            getAccessTokenFromWX(appId, appSecret);
        }
        String accessTokenStr = jsonData.getString("access_token");
        String expiresInStr = jsonData.getString("expires_in");
        AccessToken accessToken = new AccessToken();
        accessToken.setAccessToken(accessTokenStr);
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.SECOND, Integer.valueOf(expiresInStr));

        accessToken.setExpiresDate(cal.getTime());
        return accessToken;
    }
}
